<?php
class SudokuController extends AppController {
	/**
	 * 162 steps
	 */
// 	public function sudoku() {
// 		$this->set('checked',false);
// 		if ($this->request->is('post')) {
// 			$start = microtime(true);		
// 			//initiate array
// 			$data = array();
// 			for ($i = 0, $n = 0; $i < 9; $i++) {
// 				for ($j = 0; $j < 9; $j++) {
// 					$data[$i][$j] = $this->request->data[$n++];
// 				}
// 			}
// 			$this->set('flag',true);
// 			//check rows & columns
// 			$tmp = array();
// 			for ($i = 0; $i < 9; $i++) {
// 				if(!$this->checkElement($data[$i])) {
// 					$this->set('flag',false);
// 				}
// 				for ($j = 0; $j < 9; $j++) {
// 					$tmp[$j] = $data[$j][$i];
// 				}
// 				if(!$this->checkElement($tmp)) {
// 					$this->set('flag',false);
// 				}				
// 			}
// 			//check 3x3
// 			for ($n = 0; $n < 9; $n+=3) {
// 				for ($a = 0; $a < 9; $a+=3) {
// 					for ($i = $n, $k = 0; $i < $n+3; $i++) {					
// 						for ($j = $a; $j < $a+3; $j++) {
// 							$tmp[$k++] = $data[$i][$j];
// 						}
// 					}
// 					if(!$this->checkElement($tmp)) {
// 						$this->set('flag',false);
// 					}
// 				}
// 			}		
// 			$time = " +++ Time excute all process: " . (microtime(true) - $start) . " +++";
// 			$this->set('time',$time);
// 			$this->set('checked',true);
// 		}		
// 	}
	
	/**
	 * 81 steps
	 */
// 	public function sudoku() {
// 		$this->set('checked',false);
// 		if ($this->request->is('post')) {
// 			$start = microtime(true);
// 			//initiate array
// 			$data = array();
// 			$elem = array(
// 				0 => array(),
// 				1 => array(),
// 				2 => array(),
// 				3 => array(),
// 				4 => array(),
// 				5 => array(),
// 				6 => array(),
// 				7 => array(),
// 				8 => array(),
// 			);
// 			for ($i = 0, $n = 0; $i < 9; $i++) {
// 				for ($j = 0; $j < 9; $j++) {
// 					$data[$i][$j] = $this->request->data[$n++];
// 				}
// 			}
// 			$this->set('flag',true);
// 			//check rows & columns
// 			$tmp = array();
// 			$d = 0;
// 			for ($i = 0; $i < 9; $i++) {
// 				if(!$this->checkElement($data[$i])) {
// 					$this->set('flag',false);
// 				}
// 				for ($j = 0; $j < 9; $j++) {
// 					$tmp[$j] = $data[$j][$i];
//  					if (floor($i/3)==0 && floor($j/3)==0) {
//  						array_push($elem[0],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==0 && floor($j/3)==1) {
//  						array_push($elem[1],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==0 && floor($j/3)==2) {
//  						array_push($elem[2],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==1 && floor($j/3)==0) {
//  						array_push($elem[3],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==1 && floor($j/3)==1) {
//  						array_push($elem[4],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==1 && floor($j/3)==2) {
//  						array_push($elem[5],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==2 && floor($j/3)==0) {
//  						array_push($elem[6],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==2 && floor($j/3)==1) {
//  						array_push($elem[7],$data[$i][$j]);
//  					}
//  					if (floor($i/3)==2 && floor($j/3)==2) {
//  						array_push($elem[8],$data[$i][$j]);
//  					}
//  					if (($i%3)==0 && $i!=0 && ($j%3)==0 && $j!=0) {
//  						if(!$this->checkElement($elem[$d])) {
//  							$this->set('flag',false);
//  						}
//  						$d++;
//  					}
// 				}
// 				if(!$this->checkElement($tmp)) {
// 					$this->set('flag',false);
// 				}
// 			}
// 			$time = " +++ Time excute all process: " . (microtime(true) - $start) . " +++";
// 			$this->set('time',$time);
// 			$this->set('checked',true);
// 		}
// 	}
	
	/**
	 * 
	 */
	public function sudoku() {
		$this->set('checked',false);
		if ($this->request->is('post')) {
			$start = microtime(true);
			//initiate array
			$json = '[[1,2,3,4,5,6,7,9,8],[4,5,6,7,8,9,1,2,3],[7,8,9,2,3,1,4,5,6],[2,1,4,5,6,8,9,3,7],[3,6,5,9,2,7,8,1,4],[8,9,7,1,4,3,2,6,5],[5,7,2,3,9,4,6,8,1],[9,4,8,6,1,5,3,7,2],[6,3,1,8,7,2,5,4,9]]';
			$data = json_decode($json);
			$edge = count($data);
			$this->set('flag',true);
			//check rows & columns
			$tmp = array();
			$elem = array();
			for ($i = 0; $i < $edge; $i++) {
				array_push($elem, array());
			}
			for ($i = 0; $i < $edge; $i++) {
				if(!$this->checkElement($data[$i])) {
					$this->set('flag',false);
				}
				for ($j = 0; $j < 9; $j++) {
					$tmp[$j] = $data[$j][$i];
					$k = String::insert(':a:b', array('a' => floor($i/3), 'b' => floor($j/3)));
					
				}
				if(!$this->checkElement($tmp)) {
					$this->set('flag',false);
				}
			}
			$time = " +++ Time excute all process: " . (microtime(true) - $start) . " +++";
			$this->set('time',$time);
			$this->set('checked',true);
		}
	}	
	
	private function checkElement($elem = array()) {
		$tmp = array_unique($elem);
		if (count($tmp) < count($elem)) {
			return false;
		}
		if (array_sum($elem) != 45) {
			return false;
		}
		for($i = 0; $i < 9; $i++) {
			if($elem[$i] < 1 || $elem[$i] > 9) {
				return false;
			}
		}
		return true;
	}
}